import {Action} from 'redux';

import immutableObject from '../common/immutableObject';
import {IView} from '../types/IView';
import {ActionType} from './ActionType';

export interface SelectedViewState {
  [designId: string]: IView;
}

export interface SelectedViewAction extends Action {
  type: ActionType;
  designId?: string;
  view?: IView;
  viewId?: string;
  style?: object;
  viewAttrs?: object;
}

function selectedViewReducer(state: SelectedViewState = {}, action: SelectedViewAction): SelectedViewState {
  switch (action.type) {
    case ActionType.ACTIVE_DESIGN:
      return _activeDesign(state, action.designId);

    case ActionType.REMOVE_DESIGN:
      return _removeDesign(state, action.designId);

    case ActionType.SELECT_VIEW:
      return _selectView(state, action.designId, action.view);

    case ActionType.UPDATE_VIEW_STYLE:
      // 更新组件属性的时候, 也需要更新一下这里面选中的组件的属性, 因为一般来说能够更新的组件都是选中的
      return _updateView(state, action.designId, action.viewId, 'style', action.style);

    case ActionType.UPDATE_VIEW_HOVER_STYLE:
      return _updateView(state, action.designId, action.viewId, 'hoverStyle', action.style);

    case ActionType.UPDATE_VIEW_ATTR:
      // 更新组件属性的时候, 也需要更新一下这里面选中的组件的属性, 因为一般来说能够更新的组件都是选中的
      return _updateView(state, action.designId, action.viewId, 'attrVals', action.viewAttrs);

    default:
      return state;
  }
}

function _activeDesign(state: SelectedViewState, designId: string): SelectedViewState {
  const hasSuchDesign = Object.keys(state).some(stateDesignId => {
    return stateDesignId === designId;
  });
  if (hasSuchDesign) {
    return state;
  }
  return {};
}

function _removeDesign(state: SelectedViewState, designId: string): SelectedViewState {
  const hasSuchDesign = Object.keys(state).some(stateDesignId => {
    return stateDesignId === designId;
  });
  if (hasSuchDesign) {
    return {};
  }
  return state;
}

function _selectView(state: SelectedViewState, designId: string, view: IView): SelectedViewState {
  return immutableObject.set(state, designId, view);
}

function _updateView(state: SelectedViewState,
                     designId: string,
                     viewId: string,
                     field: 'attrVals' | 'style' | 'hoverStyle',
                     fieldValue?: object): SelectedViewState {
  const selectedView: IView = state[designId];

  if (!selectedView || selectedView.id !== viewId) {
    // 需要判断一下更新属性的组件是不是当前选中的那个
    return state;
  }

  const newView: IView = {...selectedView};

  newView[field] = immutableObject.extend(newView[field], fieldValue);

  return immutableObject.set(state, designId, newView) as SelectedViewState;
}

export default selectedViewReducer;
